home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
DDJ0992.ARJ
/
DBMAIN.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-07-07
|
17KB
|
402 lines
;dbmain.asm
;Debugger int 1 and main processing module
;
.386P
;----------------------------------------------------------------------------
;Copyright 1991, 1992 ASMicro Co.
;7/6/91 Rick Knoblaugh
;-----------------------------------------------------------------------------
include dbequ.inc
include dbstruc.inc
data segment para public 'data16' use16
extrn save_curs_pos:word, config_attrib:byte, debug_page:byte
extrn firstf:byte, wrk_vid_offset:word, io_instrucf:byte
extrn trace_count:word, user_page:byte, get_out:word
extrn edit_routine:word, cmd_buffer:byte, int1_active:byte
extrn io_bpdat:byte, num_io_bp:byte
extrn io_inst_port:word, io_inst_info:byte, tuser_ip:word
extrn tuser_cs:word, video_seg:word
data ends
dbstack3 segment para stack 'data16' use16
extrn db_sp3:abs
dbstack3 ends
zcode segment para public 'code16' use16
extrn get_cursor_pos:near, ck_exec_bp:near
extrn get_cursor_pos:near, clear_window:near
extrn set_video_page:near, calc_offset:near, prt_prompt:near
extrn show_regs:near, scroll_cmds_up:near, reset_trap:near
extrn set_trap:near, tmp_disable_all:near
extrn tmp_disable_io:near, set_video_page:near
extrn set_cursor_pos:near, reset_tmp_dis:near
extrn reset_tmp_io:near, editor:near
extrn clear_buffer:near, do_the_cmd:near, skip_white_sp:near
public int_1_isr, clear_shift, process_debug
public xudflag, xud_ip, xud_cs, xud_int, uflags
assume cs:zcode, ds:data, es:nothing
uflagshigh dw (mask vmbit or mask resumef) shr 16
uflags dw ?
ucs dw ?
uip dw ?
usp dw ?
uss dw ?
xudflag db FALSE ;TRUE if exit to user debugger
xud_int db 0 ;int to enter user debug
xud_ip dw 0 ;ip of ISR for user debug int
xud_cs dw 0 ;cs of ISR for user debug int
;----------------------------------------------------------------------
;int_1_isr - Interrupt service routine for int 1 |
; |
;----------------------------------------------------------------------
int_1_isr proc far
pop cs:uip ;get user return address
pop cs:ucs
pop cs:uflags
mov cs:usp, sp ;get user stack
mov sp, ss
mov cs:uss, sp
mov sp, dbstack3 ;set up own stack
mov ss, sp
mov sp, db_sp3
push cs:uflags ;put user flags, cs, ip on our stack
push cs:ucs
push cs:uip
pusha
push ds
push es
push fs
push gs
push cs:uss
push cs:usp
mov bp, sp
push eax
push ebx
push edx
cld
mov ax, DATA
mov ds, ax
int_1_050:
;
;Check to see if this break point was triggered by debug registers (1-3)
;with an execution type break point. If so, we are about to
;execute that instruction and want to break just after it. Thus, if this
;is the case, temporarily disable the break point and set trap flag so
;break can happen after the instruction completes. ck_exec_bp does all of
;this. It returns with carry set if an execution break point was detected.
;As soon as "P" command is implemented, that logic should be used
;in place of this single step method of getting to the next instruction. The
;single step method will be off when stepping across software interrupts (trap
;flag is cleared).
;ck_exec_bp also checks to see if the user is tracing using another debugger.
;If this is the case, we will not enter DB.
call ck_exec_bp
jc int_1_700 ;if execution break point
int_1_100:
call tmp_disable_io
cmp io_instrucf, TRUE ;tracing through i/o?
jne short int_1_150
cmp trace_count, 1 ;tracing when I/O happened?
jae short int_1_130
call reset_trap
int_1_130:
call ck_io_cond ;see if rest of conditions met
jnc int_1_690 ;exit if not
int_1_150:
call tmp_disable_all ;temporarily disable all bps
;
;Note: This version of the debugger makes absolutely no attempt to verify
; video mode. Logic to handle this (e.g. saving graphics etc.
; should be added here).
;
call get_cursor_pos ;get active page and cursor
mov save_curs_pos, ax
mov user_page, dl
mov ax, video_seg ;segment for video
mov es, ax
mov ah, config_attrib ;desired attribute
mov al, ' ' ;char to use for clear
mov bl, debug_page ;page for debug display
mov dx, 0000h ;upper left
mov cx, 184fh ;lower right
cmp firstf, TRUE ;first time in debugger?
jne int_1_300
mov firstf, FALSE ;not first time anymore
call clear_window
mov cx, ( (DEBUG_ROW SHL 8) OR DEBUG_COL )
call calc_offset
mov di, ax ;video offset in words
shl di, 1
mov wrk_vid_offset, di ;save prompt location
int_1_300:
call set_video_page
mov di, wrk_vid_offset ;get prompt location
call prt_prompt ;print prompt
call show_regs ;display regs as we enter
call scroll_cmds_up
int_1_400:
cmp trace_count, 1 ;doing trace n?
jb short int_1_500
jne short int_1_450
call reset_trap
mov trace_count, 0
jmp short int_1_500
int_1_450:
call set_trap
dec trace_count
mov ax, [bp].regs_ip
mov tuser_ip, ax
mov ax, [bp].regs_cs
mov tuser_cs, ax
sti
jmp short int_1_600
int_1_500:
;
;Ok now to allow interrupts. If user has set break points which might
;occur during interrupts, we will not be interrupted (i.e. debug register
;type break points and I/O break points are disabled and V86 monitor will
;not generate int 1 on INT break points when it detects user is in the
;debugger.
;
sti
call process_debug
int_1_600:
mov bl, user_page ;restore user page
call set_video_page
mov cx, save_curs_pos
mov bl, user_page ;restore user page
call calc_offset
call set_cursor_pos
int_1_650:
;reset break points which may have been temporarily disabled.
cli
call reset_tmp_dis
int_1_690:
call reset_tmp_io
mov io_instrucf, FALSE ;clear i/o flag
int_1_700:
mov int1_active, FALSE ;out of debugger
call clear_shift
pop edx
pop ebx
pop eax
pop cs:usp
pop cs:uss
pop gs
pop fs
pop es
pop ds
popa
pop cs:uip ;get user return address
pop cs:ucs
pop cs:uflags
mov sp, cs:uss ;restore user stack
mov ss, cs:uss
mov sp, cs:usp
cmp cs:xudflag, TRUE ;exit to user debugger?
je short int_1_750 ;if so, fix stack and go there
push cs:uflagshigh ;resume flag set
push cs:uflags ;user flags
push 0
push cs:ucs ;and return address
push 0
push cs:uip
iretd ;return to application
int_1_750:
push cs:uflags ;user flags
push cs:ucs ;and return address
push cs:uip
mov cs:xudflag, FALSE ;reset flag
;
;Enter user debugger with ints cleared
;
and cs:uflags, not ( (mask inter) + (mask trapf))
push cs:uflagshigh ;resume flag set
push cs:uflags ;user flags
push 0
push cs:xud_cs ;user debugger int cs
push 0
push cs:xud_ip ;user debugger int ip
iretd
int_1_isr endp
clear_shift proc near
push ds
mov ax, 40h ;BIOS data area
mov ds, ax
mov bx, KBD_FLAG
and byte ptr [bx], NOT LR_SHIFT
pop ds
ret
clear_shift endp
;----------------------------------------------------------------------
;process_debug - Accept and process user commands. |
; |
; Enter: es = video segment |
; di = offset into video buffer of first |
; position for user input |
; ds = debugger data segment |
; |
;----------------------------------------------------------------------
process_debug proc near
mov di, wrk_vid_offset ;get prompt location
call prt_prompt ;print prompt
call clear_buffer
mov si, offset cmd_buffer
process_d050:
mov dx, CMD_MAX_LEN ;max in dl, dh=zero
xor bx, bx ;char counter
mov get_out, bx ;no "get out" key
mov edit_routine, bx ;no special edit
process_d100:
call editor
process_d150:
cmp al, ESC_KEY ;esc
je short process_d300
process_d200: ;ENTER key
or dh, dh ;any chars entered?
jz short process_debug
process_d250:
movzx cx, dh ;max chars entered
call skip_white_sp
jcxz process_debug ;if just spaces entered
;
;do_the_cmd will return with carry set if cmd processed keeps us in the
;cmd loop. Otherwise, we IRET and get control on next int 1.
;
call do_the_cmd
jc short process_debug
process_d300: ;ESC key
ret
process_debug endp
;----------------------------------------------------------------------
;ck_io_cond - Debugger was entered due to an I/O instruction which |
; accessed one of the ports referenced in a BPIO command. |
; Determine if the other conditions specified in the |
; BPIO command(s) have been met. |
; |
; Note: currently, the only conditions to check for are |
; Read or Write. In the future logic can be added |
; to the BPIO command and this routine to compare |
; on specific values read or written. io_inst_info|
; will contain codes indicating type of instruc- |
; tion ( string, any segment overrides, access |
; size, etc.). This could be used to retrieve the |
; value being input or output and make comparisons |
; with user specified conditions. The structure |
; used for controlling I/O break points, info_io, |
; already has the provision for this. |
; |
; If the I/O instruction matches the user specified |
; break point condition, return with carry set else |
; return with carry clear. |
; |
; |
; Enter: ds = debugger data segment |
; |
; io_instrucf = TRUE |
; |
; io_inst_port = port address being accessed |
; |
; io_inst_info = information about the instruction |
; |
; Exit: carry set if condition(s) met |
; |
; carry clear if condition(s) not met (debugger |
; will be exited) |
; |
;----------------------------------------------------------------------
ck_io_cond proc near
mov al, io_inst_info ;info regarding instruction
mov dx, io_inst_port ;port that was accessed
sub ch, ch
mov cl, num_io_bp ;number of I/O type break points
mov bx, offset io_bpdat
jmp short ck_io_200
ck_io_100:
add bx, size info_io ;advance to next entry
ck_io_200:
cmp [bx].io_stat, AVAIL ;is this one defined?
je short ck_io_100 ;if not, check next one
cmp dx, [bx].io_port ;get port address
jne short ck_io_500
push ax
mov ah, [bx].io_dir
and ax, ( (INPUT OR OUTPUT) SHL 8) OR \
(INPUT OR OUTPUT) ;isolate direction
test ah, al ;direction match what user specified?
pop ax
jz short ck_io_500 ;if not
;
;Check other conditions here when additional conditions are implemented.
;
stc
ret
ck_io_500:
loop ck_io_100 ;see if other breakpoints on this I/O
clc
ck_io_999:
ret
ck_io_cond endp
zcode ends
end